using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using TokenRange = Org.Apache.Cassandra.Thrift.TokenRange;
using HConnectionManager = Me.Prettyprint.Cassandra.Connection.HConnectionManager;
using CassandraHost = Me.Prettyprint.Cassandra.Service.CassandraHost;
using ColumnFamilyDefinition = Me.Prettyprint.Hector.Api.Ddl.ColumnFamilyDefinition;
using KeyspaceDefinition = Me.Prettyprint.Hector.Api.Ddl.KeyspaceDefinition;
using HectorException = Me.Prettyprint.Hector.Api.Exceptions.HectorException;

namespace Me.Prettyprint.Hector.Api
{
	public interface Cluster
	{
        List<CassandraHost> KnownPoolHosts(bool refresh);
        HConnectionManager ConnectionManager
        {
            get;
        }
        /// <summary>
        /// Adds the host to this Cluster. Unless skipApplyConfig is set to true, the settings in
        /// the CassandraHostConfigurator will be applied to the provided CassandraHost
        /// </summary>
        /// <param name="host"></param>
        /// <param name="skipApplyConfig"></param>
        void AddHost(CassandraHost host, bool skipApplyConfig);
        /// <summary>
        /// Descriptive name of the cluster. The name is used to identify the cluster
        /// </summary>
        string Name
        {
            get;
        }
        string DescribeClusterName();
        string DescribeThriftVersion();
        Dictionary<string,List<string>> DescribeSchemaVersions();
        KeyspaceDefinition DescribeKeyspace(string keyspace);
        List<KeyspaceDefinition> DescribeKeyspaces();
        List<TokenRange> DescribeRing(string keyspace);
        string DescribePartitioner();
        /// <summary>
        /// Drops the Keyspace from the cluster. Equivalent of 'drop database' in SQL terms.
        /// Does not wait for schema agreement.
        /// </summary>
        /// <param name="keyspace"></param>
        /// <returns></returns>
        string DropKeyspace(string keyspace);
        /// <summary>
        /// Drops a Keyspace and waits for schema cluster agreement if waitForSchemaAgreement
        /// is set to true.
        /// </summary>
        /// <param name="keyspace"></param>
        /// <param name="waitForSchemaAgreement"></param>
        /// <returns></returns>
        string DropKeyspace(string keyspace, bool waitForSchemaAgreement);
        /// <summary>
        /// Updates the Keyspace from the cluster without waiting for schema agreement.
        /// </summary>
        /// <param name="ksdef"></param>
        /// <returns></returns>
        string UpdateKeyspace(KeyspaceDefinition ksdef);
        /// <summary>
        /// Updates the Keyspace and waitz for schema cluster agreement if waitForSchemaAgreement
        /// is set to true.
        /// </summary>
        /// <param name="ksdef"></param>
        /// <param name="waitForSchemaAgreement"></param>
        /// <returns></returns>
        string UpdateKeyspace(KeyspaceDefinition ksdef, bool waitForSchemaAgreement);
        /// <summary>
        /// Add a column family and returns without waiting for schema cluster agreement.
        /// </summary>
        /// <param name="cfdef"></param>
        /// <returns></returns>
        string AddColumnFamily(ColumnFamilyDefinition cfdef);
        /// <summary>
        /// Add a column family and wait for schema cluster agreement if waitForSchemaAgreement
        /// is set to true.
        /// </summary>
        /// <param name="cfdef"></param>
        /// <param name="waitForSchemaAgreement"></param>
        /// <returns></returns>
        string AddColumnFamily(ColumnFamilyDefinition cfdef, bool waitForSchemaAgreement);
        /// <summary>
        /// Drops a column family and does not wait for schema agreement.
        /// </summary>
        /// <param name="keyspaceName"></param>
        /// <param name="columnFamily"></param>
        /// <returns></returns>
        string DropColumnFamily(string keyspaceName, string columnFamily);
        /// <summary>
        /// Drops a column family and waits for schema cluster agreement if waitForSchemaAgreement
        /// is set to true.
        /// </summary>
        /// <param name="keyspaceName"></param>
        /// <param name="columnFamily"></param>
        /// <param name="waitForSchemaAgreement"></param>
        /// <returns></returns>
        string DropColumnFamily(string keyspaceName, string columnFamily, bool waitForSchemaAgreement);
        /// <summary>
        /// Updates a column family and does not wait for schema agreement.
        /// </summary>
        /// <param name="cfdef"></param>
        /// <returns></returns>
        string UpdateColumnFamily(ColumnFamilyDefinition cfdef);
        /// <summary>
        /// Update a column family and waits for schema cluster agreement if waitForSchemaAgreement
        /// is set to true.
        /// </summary>
        /// <param name="cfdef"></param>
        /// <param name="waitForSchemaAgreement"></param>
        /// <returns></returns>
        string UpdateColumnFamily(ColumnFamilyDefinition cfdef, bool waitForSchemaAgreement);
        /// <summary>
        /// Add a keyspace and does not wait for schema agreement.
        /// </summary>
        /// <param name="ksdef"></param>
        /// <returns></returns>
        string AddKeyspace(KeyspaceDefinition ksdef);
        /// <summary>
        /// Add a keyspace and waits for schema cluster agreement if waitForSchemaAgreement
        /// is set to true.
        /// </summary>
        /// <param name="ksdef"></param>
        /// <param name="waitForSchemaAgreement"></param>
        /// <returns></returns>
        string AddKeyspace(KeyspaceDefinition ksdef, bool waitForSchemaAgreement);
        /// <summary>
        /// Truncate will remove the data in a ColumnFamily just like SQL truncate
        /// </summary>
        /// <param name="keyspaceName"></param>
        /// <param name="columnFamily"></param>
        void Truncate(string keyspaceName, string columnFamily);
        Dictionary<string, string> Credentials
        {
            get;
        }
        /// <summary>
        /// called after the cluster has been initialized.  Default implementation is to do nothing
        /// </summary>
        void OnStartup();
	}
}